﻿using System;
using System.Collections;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace ASPNETVN.PORTAL.Components.Configuration.Settings
{
    public class PortalSettingTable : WebControl, INamingContainer
    {
        public void UpdateControls(int moduleID)
        {
            ArrayList settingItems = new ArrayList();
            foreach (string key in this._EditControls.Keys)
            {
                Control c = (Control)EditControls[key];
                PortalSettingItem currentItem = (PortalSettingItem)this._Settings[c.ID];
                currentItem.EditControl = c;
                settingItems.Add(currentItem);
            }
            PortalSettingItem[] list = (PortalSettingItem[])settingItems.ToArray(typeof(PortalSettingItem));
            //Configuration.UpdatePortal(moduleID, list);
        }

        private readonly Hashtable _EditControls = new Hashtable();
        private SortedList _Settings;

        public object DataSource
        {
            get { return this._Settings; }
            set
            {
                if (value == null || value is SortedList)
                {
                    this._Settings = (SortedList)value;
                }
                else
                {
                    throw new ArgumentException("DataSource must be SortedList type");
                }
            }
        }

        protected virtual Hashtable EditControls
        {
            get
            {
                return this._EditControls;
            }
        }

        public override void DataBind()
        {
            base.OnDataBinding(EventArgs.Empty);
            Controls.Clear();
            ClearChildViewState();
            TrackViewState();

            CreateControlHierarchy(true);
            ChildControlsCreated = true;
        }

        protected override void CreateChildControls()
        {
            Controls.Clear();
        }

        protected virtual void CreateControlHierarchy(bool useDataSource)
        {
            SortedList orderedSettings = processDataSource();
            createGroup(useDataSource, orderedSettings);
        }

        private void createGroup(bool useDataSource, SortedList settingsOrder)
        {
            if (settingsOrder.GetKeyList() == null)
            {
                return;
            }

            if (!useDataSource)
            {
                return;
            }

            HtmlGenericControl _fieldset = new HtmlGenericControl("dummy");

            Table _tbl = new Table();

            // Initialize controls
            PortalSettingItemGroup currentGroup = PortalSettingItemGroup.None;

            foreach (string currentSetting in settingsOrder.GetValueList())
            {
                PortalSettingItem currentItem = (PortalSettingItem)this._Settings[currentSetting];

                if (currentItem.Group != currentGroup)
                {
                    if (_fieldset.Attributes.Count > 0)
                    {
                        _fieldset.Controls.Add(_tbl);
                        this.Controls.Add(_fieldset);
                    }

                    // Start a new fieldset.
                    _fieldset = createNewFieldSet(currentItem);

                    // Start a new table.
                    _tbl = new Table();
                    _tbl.Attributes.Add("class", "SettingsTableGroup");
                    _tbl.Attributes.Add("width", "100%");
                    currentGroup = currentItem.Group;
                }
                _tbl.Rows.Add(createOneSettingRow(currentSetting, currentItem));
            }

            _fieldset.Controls.Add(_tbl);
            this.Controls.Add(_fieldset);
        }

        private TableRow createOneSettingRow(string currentSetting, PortalSettingItem currentItem)
        {
            // Tạo 1 TableRow với 3 TableCell. 
            TableRow row = new TableRow();

            // TableCell for help icon and description.
            TableCell helpCell = new TableCell();
            helpCell.Attributes.Add("width", "1%");
            Image img = new Image();
            img.ImageUrl = "~/Images/Icons/Help.gif";
            helpCell.Controls.Add(img);

            // Add help cell to the row.
            row.Cells.Add(helpCell);

            // Setting Name cell
            TableCell nameCell = new TableCell();
            nameCell.Attributes.Add("width", "1%");
            nameCell.Attributes.Add("style", "white-space:nowrap; padding:6px");
            nameCell.CssClass = "SubHead";
            Literal nameText = new Literal();
            nameText.Text = currentItem.Name;
            nameCell.Controls.Add(nameText);

            // Add name cell to the row.
            row.Cells.Add(nameCell);

            // Setting Control cell
            TableCell settingCell = new TableCell();
            settingCell.Attributes.Add("width", "100%");
            settingCell.CssClass = "SubSubHead";

            Control editControl;
            try
            {
                editControl = currentItem.EditControl;
                editControl.ID = currentSetting;
                editControl.EnableViewState = true;
            }
            catch (Exception ex)
            {
                editControl = new LiteralControl("There was an error loading this control: " + ex.Message);
            }
            settingCell.Controls.Add(editControl);

            //nameText.LabelForControl = editControl.ClientID;

            //Add control to edit controls collection
            this._EditControls.Add(currentSetting, editControl);

            //Validators
            /*
            settingCell.Controls.Add(new LiteralControl("<br />"));

            //Required
            if (currentItem.Required && !(editControl is EasyListBox))
            {
                RequiredFieldValidator req = new RequiredFieldValidator();
                req.ErrorMessage = Esperantus.Localize.GetString("SETTING_REQUIRED", "%1% is required!", req).Replace("%1%", currentSetting);
                req.ControlToValidate = currentSetting;
                req.CssClass = "Error";
                req.Display = ValidatorDisplay.Dynamic;
                req.EnableClientScript = true;
                settingCell.Controls.Add(req);
            }

            //Range Validator
            if (currentItem.MinValue != 0 || currentItem.MaxValue != 0)
            {
                RangeValidator rang = new RangeValidator();

                switch (currentItem.DataType)
                {

                    case PropertiesDataType.String:
                        rang.Type = ValidationDataType.String;
                        break;

                    case PropertiesDataType.Integer:
                        rang.Type = ValidationDataType.Integer;
                        break;

                    case PropertiesDataType.Currency:
                        rang.Type = ValidationDataType.Currency;
                        break;

                    case PropertiesDataType.Date:
                        rang.Type = ValidationDataType.Date;
                        break;

                    case PropertiesDataType.Double:
                        rang.Type = ValidationDataType.Double;
                        break;
                }

                if (currentItem.MinValue >= 0 && currentItem.MaxValue >= currentItem.MinValue)
                {
                    rang.MinimumValue = currentItem.MinValue.ToString();

                    if (currentItem.MaxValue == 0)
                    {
                        rang.ErrorMessage = Esperantus.Localize.GetString("SETTING_EQUAL_OR_GREATER", "%1% must be equal or greater than %2%!", rang).Replace("%1%", currentSetting).Replace("%2%", currentItem.MinValue.ToString());
                    }
                    else
                    {
                        rang.MaximumValue = currentItem.MaxValue.ToString();
                        rang.ErrorMessage = Esperantus.Localize.GetString("SETTING_BETWEEN", "%1% must be between %2% and %3%!", rang).Replace("%1%", currentSetting).Replace("%2%", currentItem.MinValue.ToString()).Replace("%3%", currentItem.MaxValue.ToString());
                    }
                }
                rang.ControlToValidate = currentSetting;
                rang.CssClass = "Error";
                rang.Display = ValidatorDisplay.Dynamic;
                rang.EnableClientScript = true;
                settingCell.Controls.Add(rang);
            }
            */

            // add setting cell into the row
            row.Cells.Add(settingCell);

            // all done send it back
            return row;
        }


        private static HtmlGenericControl createNewFieldSet(PortalSettingItem currentItem)
        {
            // start a new fieldset
            HtmlGenericControl fieldset = new HtmlGenericControl("fieldset");
            fieldset.Attributes.Add("class", string.Concat("SettingsTableGroup ", currentItem.Group.ToString().ToLower()));

            // create group legend
            HtmlGenericControl legend = new HtmlGenericControl("legend");
            legend.Attributes.Add("class", "SubSubHead");
            Literal legendText = new Literal();
            legendText.Text = currentItem.GroupDescription;
            legend.Controls.Add(legendText);
            fieldset.Controls.Add(legend);

            return fieldset;
        }

        protected virtual SortedList processDataSource()
        {
            SortedList settingsOrder = new SortedList();
            foreach (string key in this._Settings.GetKeyList())
            {
                if (this._Settings[key] != null)
                {
                    if (this._Settings[key] is PortalSettingItem)
                    {
                        int order = ((PortalSettingItem)this._Settings[key]).SortOrder;

                        while (settingsOrder.ContainsKey(order))
                        {
                            order++;
                        }
                        settingsOrder.Add(order, key);
                    }
                    else
                    {
                        throw new Exception("Errors in setting table");
                    }
                }
            }
            return settingsOrder;
        }
    }
}